using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Data;

namespace ContractDocumentation
{
    class ClassVisualizer
    {
        internal static IEnumerable<FrameworkElement> VisualizeClass(Context context, XmlClass xmlClass)
        {
            var children = new List<FrameworkElement>();
            Grid grid = new Grid();
            children.Add(grid);
            grid.Resources = context.ResourceDictionary;

            Rectangle rectangle = new Rectangle()
            {
                RadiusX = 12,
                RadiusY = 12,
                Stroke = Brushes.Black,
                StrokeThickness = 1,
                StrokeDashOffset = 2.5,
                StrokeDashCap = PenLineCap.Round,
                StrokeLineJoin = PenLineJoin.Round,
            };
            grid.Children.Insert(0, rectangle);

            StackPanel stackPanel = new StackPanel();
            grid.Children.Insert(0, stackPanel);

            var brush = new LinearGradientBrush();
            brush.GradientStops.Add(new GradientStop(Colors.LightGreen, 0));
            brush.GradientStops.Add(new GradientStop(Colors.White, 1));
            TextBlock nameTextBlock = new TextBlock()
            {
                Background = brush,
                Padding = new Thickness(16, 4, 16, 4),
            };
            stackPanel.Children.Add(nameTextBlock);
            Bold classNameBold = new Bold();
            classNameBold.Inlines.Add(xmlClass.Name.LocalName);
            nameTextBlock.Inlines.Add(classNameBold);

            if (xmlClass.Documentation != null && xmlClass.Documentation.Length > 0)
            {
                TextBlock documentationTextBlock = new TextBlock()
                {
                    Text = xmlClass.Documentation,
                    Foreground = Brushes.Gray,
                    Padding = new Thickness(16, 4, 16, 4),
                    MaxWidth = 512,
                    TextWrapping = TextWrapping.Wrap,
                };
                stackPanel.Children.Add(documentationTextBlock);
            }

            ItemsControl itemsControl = new ItemsControl();
            stackPanel.Children.Add(itemsControl);
            itemsControl.Padding = new Thickness(16, 8, 16, 8);
            itemsControl.ItemTemplate = (DataTemplate)itemsControl.FindResource("MethodTemplate");
            itemsControl.ItemsSource = xmlClass.Methods;

            grid.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
            stackPanel.Clip = new RectangleGeometry()
            {
                Rect = new Rect(new Point(0.5, 0.5), new Size(stackPanel.DesiredSize.Width - 1, stackPanel.DesiredSize.Height - 1)),
                RadiusX = 12,
                RadiusY = 12,
            };

            return children;
        }
    }

    [ValueConversion(typeof(XmlMethod), typeof(string))]
    public class MethodValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            XmlMethod xmlMethod = (XmlMethod)value;
            string s = xmlMethod.Name.LocalName + "(";
            var p = from param in xmlMethod.Parameters
                        select param.XmlType.GetSimpleName() + " " + param.Name.LocalName;
            s += string.Join(", ", p.ToArray());
            s += ") : ";
            s += xmlMethod.ReturnValue != null && xmlMethod.ReturnValue.XmlType != null ? xmlMethod.ReturnValue.XmlType.GetSimpleName() : "void";
            return s;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }

}
